# This Python file uses the following encoding: utf-8
import os
import sys
import argparse
import platform
import json
import time
import shutil

cur_platfm = platform.system().lower()
ROOT_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
BOARDS_FUNC = lambda a: [b for b in a]

def error(log = "", exit_num = 127):
    print("[ERROR]: " + log)
    sys.exit(exit_num)


def new_command_parser():
    with open("./haloos_build_config.json", 'r', encoding='utf-8') as f:
        cfg = json.loads(f.read())
        parser = argparse.ArgumentParser(description="HaloOS Build")
        parser.add_argument("-app_name", type=str, choices=BOARDS_FUNC(cfg["app_names"]), default=None, \
                            help=str(BOARDS_FUNC(cfg["app_names"])))
    return parser


def pre_process():
    with open("./haloos_build_config.json", 'r', encoding='utf-8') as f:
        cfg = json.loads(f.read())
        symlink_data = cfg["symlink_data"]
        for dir in symlink_data:
            src = os.path.abspath(os.path.join(ROOT_PATH, dir["src"]))
            dst = os.path.abspath(os.path.join(ROOT_PATH, dir["dst"]))
            symlink_dir(src, dst)


def symlink_dir(src_dir="", link_dir=""):
    if os.path.exists(src_dir):
        if os.path.lexists(link_dir):
            try:
                if os.path.islink(link_dir):
                    os.unlink(link_dir)
                elif os.path.isfile(link_dir):
                    os.remove(link_dir)
                elif os.path.isdir(link_dir):
                    shutil.rmtree(link_dir)
                else:
                    print(f"link_dir is not exists: {link_dir}")
            except Exception as e:
                print(f"delete {link_dir} failed: {e}")
        try:
            os.symlink(os.path.relpath(src_dir, os.path.dirname(link_dir)), \
                link_dir, target_is_directory=True)
        except OSError as e:
            error(f"[ERROR] create symlink link_dir: {link_dir} failed, {e}")


def app_and_system_list():
    with open("./haloos_build_config.json", 'r', encoding='utf-8') as f:
        cfg = json.loads(f.read())
        sub_os = []
        app_and_system = []
        for app_name in cfg["app_names"]:
            for datas in cfg[app_name]:
                sub_os.append(datas["sub_os"])
                sub_os = list(set(sub_os))
                app_and_system.append(f'{app_name}:{datas["sub_os"]}')
                app_and_system = list(set(app_and_system))
    return sub_os, app_and_system


def adapt_vbs_build(cmd, system):
    if system != "vbs":
        return cmd

    if cur_platfm == "windows":
        return cmd.replace("lunch linux", "lunch MINGW")
    elif cur_platfm == "linux":
        return cmd.replace("lunch MINGW", "lunch linux")
    else:
        error(f"Not support this platform [{cur_platfm}]")


def build_app(info, app):
    print("build real app name: ", app)
    for app_data in info[app]:
        system = app_data["sub_os"]
        build = f'{system}_build'
        os.chdir(os.path.join(ROOT_PATH, info[build]['path']))
        cmd = f'{info[build]["boot"]} {app_data["extra_args"]}'
        cmd = adapt_vbs_build(cmd, system)
        ret = os.system(cmd)
        if ret:
            error(f"Build {app} failed, ret: {ret}")
    return 0


def run_app_build(app):
    with open("./haloos_build_config.json", 'r', encoding='utf-8') as f:
        info = json.loads(f.read())
        if info.get(app) is None:
            for real_app_name in info["app_names"][app]:
                build_app(info, real_app_name)
        else:
            build_app(info, app)


def run_build_all():
    with open("./haloos_build_config.json", 'r', encoding='utf-8') as f:
        info = json.loads(f.read())
    for app in info["app_names"]:
        run_app_build(app)


def run_main(args):
    app = args.app_name
    if app is not None:
        # app 有效性由参数解析进行验证，后续流程中无需额外检查
        print(f"Start build with [{app}].")
        run_app_build(app)
        print(f"End build with [{app}].")
    else:
        print("Start build all apps")
        run_build_all()
        print("End build all apps")


if __name__ == "__main__":
    start = time.time()
    parser = new_command_parser()
    args = parser.parse_args()
    pre_process()
    run_main(args)
    end = time.time()
    eclipsed = end - start
    print("Elapsed %0.2f s" % eclipsed)
